package communication.common.business.util;

import communication.common.business.base.FcrSocketAddress;
import communication.common.business.base.MsgData;
import io.vertx.core.Promise;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.datagram.DatagramPacket;
import io.vertx.core.datagram.DatagramSocket;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

/**
 * @author zxl
 */
@Slf4j
public class NetSocketUtil {

    public static void sendString(NetSocket socket,String msg){
        Buffer buffer = Buffer.buffer();
        buffer.appendString(msg);
        sendData(socket,buffer);
    }

    public static void sendMsgData(NetSocket socket, MsgData msgData){
        sendObj(socket,msgData);
    }


    public static void sendData(NetSocket socket,Buffer buffer){
        if(buffer == null ){
            return;
        }

        socket.write(buffer, res->{
            if(res.succeeded()){
                log.debug("tcp socket:{} send msg:{} success !",socket.remoteAddress().toString(),buffer.toString());
            }else {
                log.warn("msg:{} send fail! cause:{}",buffer.toString(),res.cause().toString());
            }
        });
    }

    public static MsgData jsonObject2MsgData(JsonObject jsonObject){
        MsgData msgData = new MsgData();
        msgData.setOp(jsonObject.getString("op"));
        msgData.setModule(jsonObject.getString("module"));
        msgData.setType(jsonObject.getInteger("type"));
        JsonArray paramArray = jsonObject.getJsonArray("opParam");
        if(paramArray!=null && paramArray.size()>0){
            msgData.setOpParam( paramArray.stream().toArray());
        }
        msgData.setResponse(jsonObject.getString("response"));
        return msgData;
    }


    // todo:
    public static MsgData datagramPacket2MsgData(DatagramPacket packet) throws IOException, ClassNotFoundException {
       return MsgDataUtil.byteArray2obj(packet.data().getBytes());
    }


    /**
     * 将 DatagramPacket 中的数据转换为 JsonObject
     * @param packet
     * @return
     */
    public static JsonObject datagramPacket2JsonObj(DatagramPacket packet){
        Buffer data = packet.data();
        return  new JsonObject(data.toString());
    }


    public static void datagramSocketSend(DatagramSocket socket ,String host,int port,Buffer buffer){
        socket.send(buffer, port ,host,result -> {
            if(result.succeeded()){
                log.debug("msg:{} send success!",buffer.toString());
            }else {
                log.warn("msg:{} send fail! cause:{}",buffer.toString(),result.cause().toString());
            }
        });
    }

    public static Promise<Boolean> sendObj(DatagramSocket socket , String host, int port, Object obj) throws IOException {
        String msg = JsonObject.mapFrom(obj).toString();
        Promise<Boolean> promise=Promise.promise();
        Buffer buffer = Buffer.buffer().appendBytes(MsgDataUtil.obj2ByteArray(obj));
        socket.send(buffer, port ,host,result -> {
            if(result.succeeded()){
                log.debug("msg:{} send success!",msg);
                promise.complete(true);
            }else {
                log.warn("msg:{} send fail! cause:{}",msg,result.cause().toString());
                promise.complete(false);
            }
        });
        return promise;
    }

    public static void sendObj(NetSocket socket , Object obj){
        String msg = JsonObject.mapFrom(obj).toString();
        Buffer buffer = Buffer.buffer();
        buffer.appendString(msg);
        sendData(socket,buffer);
    }

    public static FcrSocketAddress getSocketAddress(io.vertx.core.net.SocketAddress socketAddress){
       return new FcrSocketAddress(socketAddress.hostAddress(),socketAddress.port());
    }

}
